<template>
  <div>
    <q-page padding>
      <q-card class="items-center row q-gutter-md q-mb-lg q-pb-lg" bordered>
        <!-- <dc-param label="test" paramType="datetime" v-model="userParams.test" /> -->

        <dc-param
          v-for="param in queryParams"
          :key="param.sqlparam_code"
          :label="param.sqlparam_name"
          :paramType="param.sqlparam_type"
          v-model="param.value"
          :paramCode="param.sqlparam_code"
        ></dc-param>
        <q-btn color="primary" @click="handleSearch" :label="$t('Search')" />
        <q-btn color="primary" @click="resetSearch" :label="$t('Reset')" />

        <q-inner-loading :showing="loadingParams">
          <q-spinner-gears size="50px" color="primary" />
        </q-inner-loading>
      </q-card>

      <!-- <q-table
        dense
        row-key="id"
        separator="cell"
        :rows="tableData"
        v-model:pagination="pagination"
        :rows-per-page-options="pageOptions"
        :loading="loading"
        @request="onRequest"
      ></q-table> -->
      <q-table
        dense
        :rows="tableData"
        separator="cell"
        :columns="columns"
        :pagination="pagination"
        :rows-per-page-options="pageOptions"
        :loading="loading"
        @request="onRequest"
      >
        <!-- <template v-slot:top-left>
          <div>SQL编码: {{ $route.meta.sql_code }}</div>
          <div>queryParams:{{ queryParams }}</div>
        </template> -->

        <template v-slot:top-right>
          <div class="row items-center q-gutter-md">
            <q-btn
              class="bg-primary text-white"
              icon="fa-solid fa-file-csv"
              no-caps
              @click="exportCsv()"
              label="导出Csv"
            />
          </div>

          <div class="row items-center q-gutter-md q-ml-xs">
            <q-btn
              class="bg-primary text-white"
              icon="fa-solid fa-table"
              no-caps
              @click="exportXlsx()"
              label="导出Excel"
            />
          </div>
        </template>

        <!-- 如果传来的值为null或undefined则不显示 -->
        <template v-slot:body-cell="props">
          <q-td :props="props">
            {{
              props.value.toLowerCase() === "null" ||
              props.value.toLowerCase() === "undefined"
                ? ""
                : props.value
            }}
          </q-td>
        </template>
        <template v-slot:loading>
          <q-inner-loading :showing="loading">
            <q-spinner-gears size="50px" color="primary" />
          </q-inner-loading>
        </template>
      </q-table>
      <div>
        {{ memo }}
      </div>
    </q-page>
  </div>
</template>

<script setup>
import { useRoute } from "vue-router";
import { useI18n } from "vue-i18n";
import { useQuasar } from "quasar";
import { computed, onBeforeMount, onMounted, ref } from "vue";
import { exportFile } from "quasar";
import { date } from "quasar";
import { onBeforeRouteUpdate } from "vue-router";
import { FormatDateTime } from "src/utils/date";
import { postAction } from "src/utils/requestAction";
import DcParam from "src/components/DcParam/DcParam.vue";
import * as XLSX from "xlsx";

const $q = useQuasar();
const { t } = useI18n();
const $route = useRoute();
const loading = ref(false);
const loadingParams = ref(false);
const hasDayId = ref("");
const sqlCode = ref($route.meta.sql_code);
const tableData = ref([]);
const columnsFromSql = ref([]);
const sqlParams = ref([]);
const queryParams = ref([]);
const pageOptions = ref([10, 20, 35, 50, 100, 0]);
const memo = ref("");

const pagination = ref({
  sortBy: "sort",
  descending: false,
  page: 1,
  rowsPerPage: 20,
});

// 获取SQL详细信息，主要是其关联的参数和SQL的memo列和has_day_id/has_month_id列
const RequestSqlInfo = async () => {
  loading.value = true;
  loadingParams.value = true;
  await postAction("sql/query-sql-by-sql-code", {
    sql_code: sqlCode.value,
  }).then((res) => {
    if (res.code === 1) {
      hasDayId.value = res.data.records.has_day_id;
      memo.value = res.data.records.memo;
      sqlParams.value = res.data.records.sqlparam;
      queryParams.value = [];
      sqlParams.value.forEach((item) => {
        queryParams.value.push({
          sqlparam_code: item.sqlparam_code,
          value: item.default_value,
          sqlparam_name: item.sqlparam_name,
          sqlparam_type: item.sqlparam_type,
        });
      });
      if (hasDayId.value === "yes") {
        queryParams.value.push({
          sqlparam_code: "begin_date",
          value: date.formatDate(new Date(), "YYYY-MM-DD"),
          sqlparam_name: "开始时间",
          sqlparam_type: "date",
          options: null,
        });
        queryParams.value.push({
          sqlparam_code: "end_date",
          value: date.formatDate(new Date(), "YYYY-MM-DD"),
          sqlparam_name: "结束时间",
          sqlparam_type: "date",
          options: null,
        });
      }
      queryParams.value.push({
        sqlparam_code: "mkt_area_name",
        value: "",
        sqlparam_name: "三级单元",
        sqlparam_type: "optionsFromQuery",
      });
      loadingParams.value = false;
    }
  });
};

// 获取报表的列属性
const RequestColumnInfo = async () => {
  loading.value = true;
  await postAction("sql/query-sql-columns-by-sql-code", {
    sql_code: sqlCode.value,
  }).then((res) => {
    if (res.code === 1) {
      columnsFromSql.value = res.data.records;
      // console.log(columnsFromSql.value);
    }
  });
};

// 获取报表的表数据
const RequestSqlData = async (params) => {
  loading.value = true;
  await postAction("sql/query-sql-result-by-sql-code", {
    sql_code: sqlCode.value,
    params: params,
  }).then((res) => {
    if (res.code === 1) {
      tableData.value = res.data.records || [];
      pagination.value.rowsNumber = res.data.total;
    }
    loading.value = false;
  });
};

const columns = computed(() => {
  return columnsFromSql.value.map((item) => {
    return {
      name: item.column_name,
      label: item.column_name,
      field: item.column_name,
      sortable: true,
      align: "center",
      width: "100px",
      format: (val, row) => {
        if (item.data_type === "datetime") {
          return `${FormatDateTime(val)}`;
        } else {
          return `${val}`;
        }
      },
    };
  });
});

const onRequest = (props) => {
  console.log(props.params);
  RequestSqlData(props.params);
};

const handleSearch = () => {
  console.log(queryParams.value);
  RequestSqlData(queryParams.value);
};
const resetSearch = () => {
  queryParams.value = {};
  RequestSqlData(queryParams.value);
};

onMounted(() => {
  RequestSqlInfo().then(() => {
    console.log(queryParams.value);
    RequestColumnInfo().then(() => {
      RequestSqlData(queryParams.value);
    });
  });
  // onRequest({ params: queryParams.value });
});

const routerUpdateWatch = onBeforeRouteUpdate(async (to, from) => {
  console.log(to.meta.sql_code);
  console.log(from.meta.sql_code);
  if (to.meta.sql_code !== from.meta.sql_code) {
    sqlCode.value = to.meta.sql_code;
    RequestSqlInfo().then(() => {
      RequestColumnInfo().then(() => {
        RequestSqlData(queryParams.value);
      });
    });
  }
});

const wrapCsvValue = (val, formatFn) => {
  let formatted = formatFn !== void 0 ? formatFn(val) : val;
  formatted =
    formatted === void 0 || formatted === null ? "" : String(formatted);
  formatted = formatted.split('"').join('""');
  /**
   * Excel accepts \n and \r in strings, but some other CSV parsers do not
   * Uncomment the next two lines to escape new lines
   */
  // .split('\n').join('\\n')
  // .split('\r').join('\\r')
  return `"${formatted}"`;
};

const exportXlsx = () => {
  // Create a new Workbook
  const wb = XLSX.utils.book_new();

  // Convert your data to a worksheet
  const wsData = [
    columns.value.map((col) => col.label),
    ...tableData.value.map((row) =>
      columns.value.map((col) =>
        typeof col.field === "function"
          ? col.field(row)
          : row[col.field === void 0 ? col.name : col.field]
      )
    ),
  ];

  const ws = XLSX.utils.aoa_to_sheet(wsData);

  // Define cell format as text for all cells (s: "text")
  ws["!cols"] = [{ s: { numFmt: "s" } }];

  // Add the worksheet to the workbook
  XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

  // Generate the Excel file as a buffer
  const xlsxfile = XLSX.write(wb, { bookType: "xlsx", type: "buffer" });

  // Export the Excel file
  const status = exportFile(
    $route.meta.sql_code +
      date.formatDate(Date.now(), "YYYY-MM-DD-HH-mm-ss") +
      ".xlsx",
    xlsxfile,
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  );

  if (status !== true) {
    $q.notify({
      message: "浏览器拒绝了文件下载...",
      color: "negative",
      icon: "warning",
    });
  }
};

const exportCsv = () => {
  // naive encoding to csv format
  const content = [columns.value.map((col) => wrapCsvValue(col.label))]
    .concat(
      tableData.value.map((row) =>
        columns.value
          .map((col) =>
            wrapCsvValue(
              typeof col.field === "function"
                ? col.field(row)
                : row[col.field === void 0 ? col.name : col.field],
              col.format
            )
          )
          .join(",")
      )
    )
    .join("\r\n");
  const status = exportFile(
    $route.meta.sql_code +
      date.formatDate(Date.now(), "YYYY-MM-DD-HH-mm-ss") +
      ".csv",
    content,
    "text/csv"
  );
  if (status !== true) {
    $q.notify({
      message: "浏览器拒绝了文件下载...",
      color: "negative",
      icon: "warning",
    });
  }
};
</script>

<script>
import { defineComponent } from "vue";

export default defineComponent({
  name: "preDefine3Comp",
});
</script>
